from flask import Flask, Response, render_template, request
import threading
import queue
import json
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='threading', cors_allowed_origins="*")  # 添加 CORS 支持

# 用于存储视频帧的队列
frame_queue = queue.Queue(maxsize=10)

# 用于存储numpy数据的队列
numpy_data_queue = queue.Queue(maxsize=10)

@app.route('/')
def index():
    """视频显示页面"""
    return render_template('index.html')

@app.route('/receive_frame', methods=['POST'])
def receive_frame():
    """接收视频帧的路由"""
    if request.method == 'POST':
        frame = request.data
        if frame_queue.full():
            frame_queue.get()  # 丢弃最旧的帧
        frame_queue.put(frame)
        return "Frame received", 200

def gen():
    """生成视频帧"""
    while True:
        if not frame_queue.empty():
            frame = frame_queue.get()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    return Response(gen(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

# ========== 添加 /video 命名空间支持 ==========
@socketio.on('connect', namespace='/video')
def handle_video_connect():
    print('Video client connected on /video namespace')

@socketio.on('disconnect', namespace='/video')
def handle_video_disconnect():
    print('Video client disconnected from /video namespace')

# ========== /numpy 命名空间处理 ==========
@socketio.on('connect', namespace='/numpy')
def handle_numpy_connect():
    print('Numpy client connected on /numpy namespace')

@socketio.on('disconnect', namespace='/numpy')
def handle_numpy_disconnect():
    print('Numpy client disconnected from /numpy namespace')

@socketio.on('numpy_data', namespace='/numpy')
def handle_numpy_data(data):
    """接收numpy数据并转发给视频客户端"""
    print(f"Server received numpy data: {data}")
    # 转发到视频客户端和网页
    socketio.emit('numpy_data_to_video', data, namespace='/video')
    socketio.emit('numpy_data_to_web', data, namespace='/web')

# ========== /web 命名空间处理 ==========
@socketio.on('connect', namespace='/web')
def handle_web_connect():
    print('Web client connected on /web namespace')

@socketio.on('disconnect', namespace='/web')
def handle_web_disconnect():
    print('Web client disconnected from /web namespace')

if __name__ == '__main__':
    # 创建模板目录
    import os
    if not os.path.exists('templates'):
        os.makedirs('templates')
    
    # 创建简单的HTML模板
    with open('templates/index.html', 'w') as f:
        f.write('''
        <!doctype html>
        <html>
        <head>
            <title>Video Stream</title>
        </head>
        <body>
            <h1>Video Stream</h1>
            <img src="{{ url_for('video_feed') }}">
            <div id="numpy-data">Waiting for data...</div>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
            <script>
                // 连接到服务端的 /web 命名空间
                var socket = io.connect('http://' + document.domain + ':' + location.port + '/web');
                
                // 接收并显示NumPy数据
                socket.on('numpy_data_to_web', function(data) {
                    document.getElementById('numpy-data').innerHTML = 
                        'Received numpy data: ' + JSON.stringify(data);
                });
            </script>
        </body>
        </html>
        ''')
    
    socketio.run(app, host='0.0.0.0', port=5000, debug=True, use_reloader=False)
